import 'dart:io';
import 'dart:ui';

import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_syt/generated/assets.dart';
import 'package:flutter_syt/widgets/auto_image.dart';
import 'package:intl/intl.dart';
import 'package:flutter_syt/api/api.dart';
import 'package:flutter_syt/application.dart';
import 'package:flutter_syt/datas/game_item.dart';
import 'package:flutter_syt/datas/user_info.dart';
import 'package:flutter_syt/datas/venue_item.dart';
import 'package:flutter_syt/domain/games/event_schedule_calendar.dart';
import 'package:flutter_syt/domain/games/event_schedule_filter.dart';
import 'package:flutter_syt/domain/games/event_schedule_model.dart';
import 'package:flutter_syt/domain/games/game_utils/game_utils_controller.dart';
import 'package:flutter_syt/domain/widgets/network_load_image.dart';
import 'package:flutter_syt/generated/l10n.dart';
import 'package:flutter_syt/theme/theme_color.dart';
import 'package:flutter_syt/utils/click_utils.dart';
import 'package:flutter_syt/utils/utils_dlog.dart';
import 'package:flutter_syt/utils/utils_other.dart';
import 'package:flutter_syt/widgets/view_state_widget.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:yyy_route_annotation/yyy_route_annotation.dart';

import '../../global_easy_loading.dart';
import '../../routes.all.dart';

class EventSchedule extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _EventScheduleState();
  }
}

class _EventScheduleState extends State<EventSchedule> {
  var isClear = true;
  var forward = 1;
  var backward = 0;
  var filter = false;
  var time = UtilsOther.getShowDate();
  EventTableViewController tableController = EventTableViewController();
  List<List<EventScheduleData>> dataList = [];
  var firstLoading = true;

  @override
  void initState() {
    _getFilterDataRequest();
    UserInfo.me.addListener(() {
      isClear = true;
      tableController.reloadData();
    });
    GameUtilsController.managerCont['2'] = tableController;
    super.initState();
  }

  Future<List<List<EventScheduleData>>> getDataSource(
      {bool more = false, RefreshController? controller}) async {
    // 初始化时默认拉下一页。
    var needEmpty = false;
    if (isClear) {
      more = true;
      forward = 1;
      backward = 0;
      isClear = false;
      needEmpty = true;
      dataList = [];
    } else if (more) {
      forward += 1;
    } else {
      backward += 1;
    }
    var month = time.month < 9 ? '0${time.month}' : time.month;
    var day = time.day < 9 ? '0${time.day}' : time.day;
    var date = "${time.year}-$month-$day";

    var res = await API.shared.game.scheduleList(
        more,
        more == true ? forward : backward,
        20,
        _getFilterData().selectMatch.discipline,
        _getFilterData().selectVenue.code,
        _getFilterData().selectState.id,
        date);
    var list = res.map((value) => EventScheduleData(value)).toList();
    // 加载更多时匹配最后一条数据是否与新返回的列表倒序后一致。用于判断是否处于同一天。
    List<EventScheduleData> last = [];
    EventScheduleData? lastItem;
    var haveEmptyData = false;
    try {
      // 获取第一组或最后一组数据
      last = more == true ? dataList.last : dataList.first;
      // 获取第一条或最后一条数据
      lastItem = more == true ? last.last : last.first;
    } catch (e) {}
    if (more) {
      for (int i = 0; i < list.length; i++) {
        var item = list[i];
        if (lastItem != null) {
          if (item.date != lastItem.date) {
            last = [];
            dataList.add(last);
          }
          last.add(item);
        } else {
          dataList.add(last);
          last.add(item);
        }
        lastItem = item;
      }
      if (needEmpty) {
        // 添加选择日期当日没有内容时添加占位
        var idx = 0;
        for (int i = dataList.length - 1; i >= 0; i--) {
          var item = dataList[i];
          var time = item.first.startDate;
          if (Comparable.compare(date, time) == 0) {
            idx = -1;
            break;
          } else if (Comparable.compare(date, time) == 1) {
            // 当日期已经小于这一天的日期的时候，代表当天没有数据，否则已经break跳出了
            idx = i;
            break;
          }
        }
        if (idx >= 0) {
          haveEmptyData = true;
          var zhLang = true;
          var local = appContext.storage.getString("storyLocal") ??
              Intl.getCurrentLocale();
          if (local.contains('zh')) {
            zhLang = true;
          } else {
            zhLang = false;
          }
          var emptyDate = EventScheduleData(
              {"date": zhLang ? "$month-$day" : "$day-$month"});
          List<EventScheduleData> empty = [emptyDate];
          dataList.insert(idx, empty);
        }
      }
    } else {
      dataList.clear();
      for (int i = list.length - 1; i >= 0; i--) {
        var item = list[i];
        if (lastItem != null) {
          if (item.date != lastItem.date) {
            last = [];
            dataList.insert(0, last);
          }
          last.add(item);
        } else {
          last.add(item);
        }
        lastItem = item;
      }
    }
    if (res.isEmpty && dataList.isNotEmpty) {
      if (dataList.length == 1 && haveEmptyData == true) {
      } else {
        // customShowToast(S.of(context).no_more);
        controller?.loadNoData();
      }
    }
    return dataList;
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      color: Color(0xfff8f8f8),
      child: Stack(
        children: [
          Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              EventScheduleCalendar(
                action: EventCalendarAction((data) {
                  if (data is DateTime) {
                    // 如果日期相同，不做处理；
                    if (isSameDay(time, data)) {
                      return;
                    }
                    time = data;
                    isClear = true;

                    setState(() {});
                    tableController.reloadData();
                  } else {
                    print('传入的不是时间');
                  }
                }, time, _getFilterData().matchTimeList),
              ),
              titleWidget(),
              Expanded(child: _list()),
            ],
          ),
          if (filter)
            Positioned.fill(
              child: Container(
                color: ThemeColor.colorBlack50,
                child: EventScheduleFilter(data: _getFilterData()),
              ),
            ),
          // ),
        ],
      ),
    );
  }

  EventFilterData? filterData;

  EventFilterData _getFilterData() {
    if (filterData == null) {
      filterData = EventFilterData(() {
        setState(() {
          filter = false;
          isClear = true;
        });
        // tableController.refresh();
        tableController.reloadData();
      }, () {
        setState(() {
          filter = false;
        });
      });
    }
    return filterData!;
  }

  Future<bool> _getFilterDataRequest() async {
    if (!firstLoading) {
      EasyLoading.instance.loadingStyle = EasyLoadingStyle.light;
      EasyLoading.show(
        status: S().loading,
        maskType: EasyLoadingMaskType.black,
        indicator: const AutoImage(
          Assets.loading,
          width: 64,
          height: 64,
        )
      );
    }
    try {
      _getFilterData().venueList = await API.shared.venue.list();
      _getFilterData().matchList = await API.shared.game.items();
      _getFilterData().matchTimeList = await API.shared.game.gameDateList();
      var allVenue = VenueItem({"id": "", "name": S().All, "code": ""});
      var allMatch =
          GameDetail({"id": "", "discipline_name": S().All, "discipline": ""});
      _getFilterData().venueList.insert(0, allVenue);
      _getFilterData().matchList.insert(0, allMatch);
      _getFilterData().stateList.addAll([
        EventStateData(S().All, '0'), EventStateData(S().not_started, '1'),
        EventStateData(S().Finished, '2'), EventStateData(S().underway, '3'),
        // EventStateData('未安排', '4')
      ]);
      EasyLoading.dismiss();
      return true;
    } on DioError catch (e) {
      EasyLoading.dismiss();
      var msg = '';
      if (e.error is SocketException) {
        msg = S().network_error;
      } else {
        msg = e.message ?? '';
      }
      customShowToast(msg);
      return false;
    } catch (e, stack) {
      EasyLoading.dismiss();
      await UtilsOther.showCustomShowError(e);
      // if (e is DioError) {
      //   customShowToast(e.message);
      // } else {
      //   customShowToast(S().network_error);
      // }
      return false;
    }
  }

  Widget titleWidget() {
    void _onTapped() async {
      if ((_getFilterData().venueList.isEmpty ||
          _getFilterData().matchList.isEmpty)) {
        var res = await _getFilterDataRequest();
        if (res) {
          _onTapped();
        }
      } else {
        setState(() {
          filter = true;
        });
      }
    }

    return Container(
      padding: EdgeInsets.only(left: 15),
      child: Row(
        children: [
          Text(
            S.of(context).schedule,
            style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600),
          ),
          Spacer(),
          IconButton(
            onPressed: _onTapped,
            icon: Image.asset(
              "assets/icons/event_filter.png",
              width: 18,
              height: 16,
              // _getFilterData().selectVenue.code,
              // _getFilterData().selectState.id,
              color: (_getFilterData().selectMatch.discipline.length > 0 ||
                      _getFilterData().selectVenue.code.length > 0 ||
                      (int.tryParse(_getFilterData().selectState.id) ?? 0) > 0)
                  ? ThemeColor.primaryColor
                  : ThemeColor.colorBlack100,
            ),
          ),
        ],
      ),
    );
  }

  Widget _list() {
    return EventTableView<List<EventScheduleData>>(
        controller: tableController,
        enableRefresh: false,
        enableLoadMore: true,
        itemBuilder: (ctx, item, idx) {
          return _cell(item, idx != 0);
        },
        getData: (preList, more, c) async {
          // return getDataSource(more: more, controller: c);
          // 初始化时默认拉下一页。
          var needEmpty = false;
          if (isClear) {
            // c.footerMode =
            // c.footerStatus = loads
            c.loadComplete();
            more = true;
            forward = 1;
            backward = 0;
            isClear = false;
            needEmpty = true;
            dataList = [];
          } else if (more) {
            forward += 1;
          } else {
            backward += 1;
          }
          var month = time.month < 9 ? '0${time.month}' : time.month;
          var day = time.day < 9 ? '0${time.day}' : time.day;
          var date = "${time.year}-$month-$day";

          var res = await API.shared.game.scheduleList(
              more,
              more == true ? forward : backward,
              20,
              _getFilterData().selectMatch.discipline,
              _getFilterData().selectVenue.code,
              _getFilterData().selectState.id,
              date);
          var list = res.map((value) => EventScheduleData(value)).toList();
          // 加载更多时匹配最后一条数据是否与新返回的列表倒序后一致。用于判断是否处于同一天。
          List<EventScheduleData> last = [];
          DLog('cvsdvamdsk   ${list.length}');
          EventScheduleData? lastItem;
          var haveEmptyData = false;
          try {
            // 获取第一组或最后一组数据
            last = more == true ? dataList.last : dataList.first;
            // 获取第一条或最后一条数据
            lastItem = more == true ? last.last : last.first;
          } catch (e) {}
          if (more) {
            for (int i = 0; i < list.length; i++) {
              var item = list[i];
              if (lastItem != null) {
                if (item.date != lastItem.date) {
                  last = [];
                  dataList.add(last);
                }
                last.add(item);
              } else {
                dataList.add(last);
                last.add(item);
              }
              lastItem = item;
            }
            if (needEmpty) {
              // 添加选择日期当日没有内容时添加占位
              var idx = 0;
              for (int i = dataList.length - 1; i >= 0; i--) {
                var item = dataList[i];
                var time = item.first.startDate;
                if (Comparable.compare(date, time) == 0) {
                  idx = -1;
                  break;
                } else if (Comparable.compare(date, time) == 1) {
                  // 当日期已经小于这一天的日期的时候，代表当天没有数据，否则已经break跳出了
                  idx = i;
                  break;
                }
              }
              if (idx >= 0) {
                haveEmptyData = true;
                var zhLang = true;
                var local = appContext.storage.getString("storyLocal") ??
                    Intl.getCurrentLocale();
                if (local.contains('zh')) {
                  zhLang = true;
                } else {
                  zhLang = false;
                }
                var emptyDate = EventScheduleData(
                    {"date": zhLang ? "$month-$day" : "$day-$month"});
                List<EventScheduleData> empty = [emptyDate];
                dataList.insert(idx, empty);
              }
            }
          } else {
            dataList.clear();
            for (int i = list.length - 1; i >= 0; i--) {
              var item = list[i];
              if (lastItem != null) {
                if (item.date != lastItem.date) {
                  last = [];
                  dataList.insert(0, last);
                }
                last.add(item);
              } else {
                last.add(item);
              }
              lastItem = item;
            }
          }
          if (res.isEmpty && dataList.isNotEmpty) {
            if (dataList.length == 1 && haveEmptyData == true) {
              // c.loadComplete();
              // c.loadComplete()
            } else {
              // customShowToast(S.of(context).no_more);
              c.loadNoData();
              // c.loadComplete()
            }
          }
          return dataList;
        });
  }

  Widget _cell(List<EventScheduleData> data, bool first) {
    var title = '';
    try {
      title = data.first.date;
    } catch (e) {}
    List<Widget> widgets = [_listTitle(title, first)];
    List<Widget> items = [];
    if (data.first.id == "null" || data.first.id.isEmpty) {
      //占位
      items.add(_emptyWidget(data.first));
    } else {
      //正常数据
      for (var i = 0; i < data.length; i++) {
        items.add(_listItem(data[i]));
      }
    }
    widgets.addAll(items);
    return Container(
        child: Column(
      children: widgets,
    ));
  }

  Widget _listTitle(String data, bool firstLine) {
    return Stack(
      children: [
        Positioned(
            child: Container(
              width: 0.5,
              height: 22,
              color: ThemeColor.dividerColor_grey,
            ),
            left: 22,
            top: 13),
        // if (firstLine)
        //   Positioned(
        //       child: Container(
        //         width: 2,
        //         height: 5,
        //         color: ThemeColor.dividerColor_grey,
        //       ),
        //       left: 19),
        Container(
          padding: EdgeInsets.only(left: 15, bottom: 8),
          child: Row(
            children: [
              Image.asset("assets/icons/event_dot.png", width: 15, height: 15),
              SizedBox(
                width: 5,
              ),
              Text(
                data,
                style: TextStyle(
                  color: ThemeColor.colorBlack60,
                  fontSize: 14,
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }

  Widget _listItem(EventScheduleData data) {
    return GestureDetector(
      onTap: ClickUtils.debounce(() {
        {
          RouteManager.push(
              context, RoutMapping.gameDetail(data.id, isVideo: false));
        }
      }),
      child: Stack(
        children: [
          Container(
              padding: EdgeInsets.only(right: 15),
              child: IntrinsicHeight(
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    SizedBox(width: 22),
                    _divider(),
                    SizedBox(width: 10),
                    Expanded(
                      child: Container(
                        decoration: BoxDecoration(
                          shape: BoxShape.rectangle,
                          borderRadius: BorderRadius.all(Radius.circular(12)),
                          color: Colors.white,
                        ),
                        padding: EdgeInsets.fromLTRB(15, 18, 15, 0),
                        margin: EdgeInsets.only(top: 3, bottom: 10),
                        child: Column(
                          mainAxisSize: MainAxisSize.min,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Row(
                              children: [
                                const SizedBox(width: 48),
                                Text(
                                  data.date,
                                  style: TextStyle(
                                      fontSize: 14,
                                      color: ThemeColor.colorBlack60),
                                ),
                                SizedBox(
                                  width: 8,
                                ),
                                Text(
                                  data.time,
                                  style: TextStyle(fontWeight: FontWeight.w400),
                                ),
                                Spacer(),
                                Text(
                                  data.statusName,
                                  style: TextStyle(
                                      fontSize: 11,
                                      fontWeight: FontWeight.w400),
                                ),
                              ],
                            ),
                            SizedBox(
                              height: 14,
                            ),
                            RichText(
                              textAlign: TextAlign.left,
                              text: TextSpan(
                                children: [
                                  WidgetSpan(
                                      child: data.videoType != 0
                                          ? Padding(
                                              padding: EdgeInsets.only(
                                                  right: 4, bottom: 2),
                                              child: data.videoType == 1
                                                  ? Image.asset(
                                                      "assets/icons/game_event_live.gif",
                                                      width: 14,
                                                      height: 14)
                                                  : Image.asset(
                                                      "assets/icons/game_event_video_ic.png",
                                                      width: 16,
                                                      height: 14),
                                            )
                                          : Text('')),
                                  TextSpan(
                                    text:
                                        "${data.disciplineName} ${data.scheduleName}",
                                    style: (TextStyle(
                                      fontWeight: FontWeight.w500,
                                      fontSize: 16,
                                      color: Colors.black.withOpacity(0.8),
                                    )),
                                  ),
                                ],
                              ),
                            ),
                            SizedBox(height: 12),
                            Row(
                              children: [
                                Image.asset(
                                    "assets/icons/schedule_location.png",
                                    width: 10,
                                    height: 11),
                                SizedBox(
                                  width: 4,
                                ),
                                Expanded(
                                  child: Text(
                                    "${data.venueName} ${data.locationName}",
                                    maxLines: 2,
                                    overflow: TextOverflow.ellipsis,
                                    style: TextStyle(
                                        fontSize: 12, color: Colors.black38),
                                  ),
                                ),
                                if (data.status != 'FINISHED')
                                  GestureDetector(
                                      onTap: ClickUtils.debounce(() async {
                                        if (!UserInfo.me.isLogin) {
                                          RouteManager.push(
                                            context,
                                            RoutMapping.loginByPwd(),
                                          );
                                          return;
                                        }
                                        if (data.subscribed) {
                                          try {
                                            await API.shared.game
                                                .cancelMatchSubscribe(data.id);
                                            data.subscribed = false;
                                            setState(() {});
                                            customShowToast(S
                                                .of(context)
                                                .unsubscribe_succeeded);
                                          } catch (e) {
                                            await UtilsOther
                                                .showCustomShowError(e);
                                            // if (e is DioError) {
                                            //   customShowToast(e.message);
                                            // } else {
                                            //   customShowToast(
                                            //       S.of(context).network_error);
                                            // }
                                          }
                                        } else {
                                          try {
                                            await API.shared.game
                                                .subscribeMatch(data.id);
                                            data.subscribed = true;
                                            setState(() {});
                                          } catch (e) {
                                            await UtilsOther
                                                .showCustomShowError(e);
                                            // if (e is DioError) {
                                            //   customShowToast(e.message);
                                            // } else {
                                            //   customShowToast(
                                            //       S.of(context).network_error);
                                            // }
                                          }
                                        }
                                      }),
                                      child: Container(
                                        height: 28,
                                        // margin: EdgeInsets.only(bottom: 12),
                                        padding: EdgeInsets.symmetric(
                                            horizontal: 16),
                                        alignment: Alignment.center,
                                        decoration: BoxDecoration(
                                          borderRadius: BorderRadius.all(
                                              Radius.circular(4)),
                                          color: data.subscribed
                                              ? Color(0xffF7D749)
                                                  .withOpacity(0.3)
                                              : Color(0xffF7D749),
                                        ),
                                        child: Text(
                                          // 'asd',
                                          data.subscribed
                                              ? S().Subscribed
                                              : S().Subscribe,
                                          maxLines: 1,
                                          style: TextStyle(
                                            color: data.subscribed
                                                ? Colors.black.withOpacity(0.6)
                                                : Colors.black,
                                            // fontWeight: FontWeight.w500,
                                            fontSize: 12,
                                          ),
                                        ),
                                      )),
                              ],
                            ),
                            if (data.status != 'FINISHED')
                              SizedBox(
                                height: 12,
                              ),
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              )),
          Positioned(
            child: Container(
              width: 43,
              height: 43,
              child: NetworkLoadImage.loadNetworkImage(data.background),
              // child: CachedNetworkImage(
              //   imageUrl: data.background,
              //   fit: BoxFit.contain,
              //   // errorWidget: (ctc, error, child) {
              //   //   return Container(color: Colors.grey);
              //   // },
              // ),
            ),
            left: 45,
          ),
          Positioned(
            child: Container(
              width: 43,
              height: 43,
              child: NetworkLoadImage.loadNetworkImage(data.cover),
              // child: CachedNetworkImage(
              //   imageUrl: data.cover,
              //   fit: BoxFit.cover,
              // ),
            ),
            left: 45,
          ),
        ],
      ),
    );
  }

  Widget _emptyWidget(EventScheduleData data) {
    return Container(
        padding: EdgeInsets.only(right: 15),
        child: IntrinsicHeight(
          child: Row(
            children: [
              SizedBox(width: 22),
              _divider(),
              SizedBox(width: 10),
              Expanded(
                  // color: Colors.red,
                  child: Center(
                child: Column(
                  children: [
                    Image.asset(
                      'assets/images/game_event_today_empty.png',
                      width: 100,
                      height: 86,
                    ),
                    SizedBox(
                      height: 12,
                    ),
                    Text(
                      S.of(context).No_concent,
                      style: TextStyle(
                        color: Color(0xff666666),
                        fontSize: 12,
                      ),
                    ),
                    SizedBox(
                      height: 20,
                    ),
                  ],
                ),
              ))
            ],
          ),
        ));
  }

  Widget _divider() {
    return VerticalDivider(
      width: 0,
      thickness: 0.5,
    );
  }
}

class EventTableViewController {
  _SubCollectState? _inState;

  void refresh() {
    // debugPrint("request refresh ---- ");
    try {
      _inState?._scrollController.jumpTo(0);
    } catch (e) {}
    _inState?._controller.requestRefresh();
  }

  void animateTo(
    double offset, {
    Duration? duration,
    Curve? curve,
  }) {
    _inState?._scrollController.animateTo(0,
        duration: duration ?? Duration(milliseconds: 300),
        curve: curve ?? Curves.bounceInOut);
  }

  void reloadData() {
    try {
      _inState?._scrollController.jumpTo(0);
    } catch (e) {}
    _inState?._loadingGetData();
  }
}

int _defaultPageSize(page) => 15;

class EventTableView<T> extends StatefulWidget {
  final Widget Function(BuildContext, T, int) itemBuilder; // 返回列表中每行Item
  final Widget Function(bool, String)? holder; // 空页面或者错误占位页面
  final EdgeInsets padding;
  final Future<List<T>> Function(
      List<T>?, bool more, RefreshController controller) getData; // 获取数据（接口函数）
  final int Function(int) pageSize; // 每页数据个数，默认15个
  final Widget Function(BuildContext)? header;
  final void Function(BuildContext context, double offset)? onScroll;
  final Widget Function(BuildContext context, String text, RefreshStatus state)?
      refreshItemBuilder;
  final EventTableViewController? controller;
  final bool enableRefresh;
  final bool enableLoadMore;
  final bool needAutoFreash;

  EventTableView({
    required this.itemBuilder,
    this.holder,
    this.header,
    required this.getData,
    this.pageSize = _defaultPageSize,
    this.padding = EdgeInsets.zero,
    this.onScroll,
    this.controller,
    this.enableRefresh = true,
    this.enableLoadMore = true,
    this.needAutoFreash = true,
    this.refreshItemBuilder,
  });

  @override
  State<StatefulWidget> createState() {
    return _SubCollectState<T>();
  }
}

class _SubCollectState<T> extends State<EventTableView<T>>
    with AutomaticKeepAliveClientMixin {
  RefreshController _controller = RefreshController(initialRefresh: false);
  ScrollController _scrollController = ScrollController();
  String? _error;
  List<T> _list = [];
  bool _firstLoading = true;

  @override
  bool get wantKeepAlive => true;
  SmartRefresher? body;

  @override
  void initState() {
    Future.delayed(Duration(milliseconds: 200)).then((value) {
      if (widget.needAutoFreash) {
        _firstLoading = true;
        _loadingGetData();
      } else {
        _firstLoading = false;
      }
      setState(() {});
    });
    widget.controller?._inState = this;
    _scrollController.addListener(() {
      if (widget.onScroll != null) {
        widget.onScroll!(context, -_scrollController.position.pixels);
      }
    });
    super.initState();
  }

  @override
  dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  reload() async {}

  //第一次获取数据的时候，显示加载loading
  _loadingGetData() async {
    try {
      _firstLoading = true;
      await _firstGetData();
    } on DioError catch (e) {
      setState(() {
        if (e.error is SocketException) {
          _error = S().network_error;
        } else {
          _error = e.message;
        }
      });
    } catch (e, stack) {
      _error = "$e";
      debugPrintStack(stackTrace: stack);
    } finally {
      setState(() {
        _firstLoading = false;
      });
    }
  }

  _firstGetData() async {
    var array = await widget.getData(_list, false, _controller);
    _controller.headerMode?.value = RefreshStatus.completed;
    setState(() {
      _error = null;
      _list = array;
    });
  }

  //下来获取数据
  void onRefresh() async {
    try {
      await _firstGetData();
      _controller.headerMode?.value = RefreshStatus.completed;
    } catch (e) {
      _controller.headerMode?.value = RefreshStatus.failed;
    }
  }

  //加载更多
  void onLoading() async {
    try {
      List<T> array = await widget.getData(_list, true, _controller);
      _list = array;
      if (array.length > 0) {
        _controller.footerMode?.value = LoadStatus.idle;
      } else {
        _controller.footerMode?.value = LoadStatus.noMore;
      }
      setState(() {});
    } catch (e) {
      _controller.footerMode?.value = LoadStatus.failed;
    }
  }

  Widget _showHolder() {
    if (_firstLoading) {
      return Container();
    }
    var child = widget.holder != null
        ? widget.holder!(_error != null, _error ?? "")
        : ViewStateEmptyWidget(
            message: _error != null ? "$_error" : null,
          );

    return Center(
      child: TextButton(
        child: child,
        onPressed: ClickUtils.debounce(() {
          _loadingGetData();
        }),
      ),
    );
  }

  Widget loading() {
    return Container(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Image.asset(
            "assets/icons/empty.png",
            width: 80,
            height: 80,
          ),
          Container(
            height: 12,
          ),
          Text(
            S.of(context).loading,
            style:
                TextStyle(color: Colors.black.withOpacity(0.4), fontSize: 14),
          ),
          Container(
            height: 20,
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    Widget child = _showHolder();
    if (_firstLoading) {
      return loading();
    } else if (_list.length > 0 || widget.header != null) {
      child = CustomScrollView(
        controller: _scrollController,
        slivers: [
          if (widget.header != null)
            SliverToBoxAdapter(
              child: widget.header!(context),
            ),
          SliverPadding(
            padding: widget.padding,
            sliver: SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, index) {
                  return widget.itemBuilder(context, _list[index], index);
                },
                childCount: _list.length,
              ),
            ),
          )
        ],
      );
    } else if (_error != null) {
      return child;
    }
    body = SmartRefresher(
      controller: _controller,
      // header: CustomHeader(
      //   height: kHeight,
      //   builder: (ctx, state) {
      //     var txt = S.of(context).loading;
      //     if (state == RefreshStatus.failed) {
      //       txt = S.of(context).load_failed;
      //     } else if (state == RefreshStatus.canRefresh) {
      //       txt = S.of(context).release_to_refresh;
      //     } else if (state == RefreshStatus.idle) {
      //       txt = S.of(context).swipe_to_refresh;
      //     } else if (state == RefreshStatus.completed) {
      //       txt = S.of(context).refreshed;
      //     }
      //     Widget headerWidget = commonRefreshStateWidget(txt, Colors.white);
      //     if (widget.refreshItemBuilder != null) {
      //       headerWidget = widget.refreshItemBuilder!(ctx, txt, state!);
      //     }
      //     return headerWidget;
      //   },
      // ),
      // footer: CustomFooter(
      //   builder: (context, state) {
      //     var txt = S.of(context).loading;
      //     if (state == LoadStatus.failed) {
      //       txt = S.of(context).load_failed;
      //     } else if (state == LoadStatus.noMore) {
      //       txt = S.of(context).no_more;
      //     } else if (state == LoadStatus.idle) {
      //       txt = S.of(context).load_more;
      //     }
      //     return Container(
      //       child: Column(
      //         crossAxisAlignment: CrossAxisAlignment.center,
      //         children: [
      //           SizedBox(
      //             height: 20,
      //           ),
      //           Image.asset(
      //             "assets/icons/refresh_footer.png",
      //             width: 36,
      //             height: 32,
      //           ),
      //           Text(
      //             txt,
      //             style: TextStyle(
      //                 color: Colors.black.withOpacity(0.4), fontSize: 11),
      //           ),
      //         ],
      //       ),
      //     );
      //   },
      // ),
      onRefresh: onRefresh,
      onLoading: onLoading,
      enablePullUp: widget.enableLoadMore,
      enablePullDown: widget.enableRefresh,
      child: child,
    );
    return body!;
  }
}
